const { app, BrowserWindow, screen, ipcMain, shell, Tray, Menu, Notification } = require('electron');
const { protocol } = require('electron');
const Store = require('electron-store');
const path = require('path');
const { dialog } = require('electron');
const fs = require('fs');
const Papa = require('papaparse');
const ini = require('ini');
const sqlite3 = require('sqlite3').verbose();
let savePreFilePath = undefined;
let mainWindow;
let notionShow = true
let appPort = 8081
let appSave = 'D:/save/'

let db = new sqlite3.Database('./db.sqlite3', (err) => {
    if (err) {
        return console.error(err.message);
    }
});
let getBackup = (key) => {
    return new Promise((resolve, reject) => {
        db.get('SELECT value FROM b_backup WHERE key =? ORDER BY id DESC LIMIT 1', [key], (err, row) => {
            if (err) {
                reject(err);
            } else {
                resolve(row?.value);
            }
        });
    });
}
let setBackup = (key, value) => {
    return new Promise((resolve, reject) => {
        db.run('UPDATE b_backup SET value =? WHERE key =?', [value, key], function (err) {
            if (err) {
                if (notionShow) {
                    errorMessage(err.message, "提示", "请该软件文件夹根目录下db.sqlite3文件属性只读，请取消只读")
                    notionShow = false
                }
                reject(err);
            } else {
                resolve();
            }
        });
    });
}

let addBackup = (key, value) => {
    return new Promise((resolve, reject) => {
        db.run('INSERT INTO b_backup (key, value) VALUES (?,?)', [key, value], function (err) {
            if (err) {
                if (notionShow) {
                    errorMessage(err.message, "提示", "请该软件文件夹根目录下db.sqlite3文件属性只读，请取消只读")
                    notionShow = false
                }
                reject(err);
            } else {
                resolve();
            }
        });
    });
}
let countBackup = (key) => {
    return new Promise((resolve, reject) => {
        db.get('SELECT COUNT(*) as count FROM b_backup WHERE key =?', [key], (err, row) => {
            if (err) {
                reject(err);
            } else {
                resolve(row && row.count ? row.count : 0)
            }
        });
    });
}

let deleteBackup = () => {
    return new Promise((resolve, reject) => {
        db.run('DELETE FROM b_backup', function (err) {
            if (err) {
                if (notionShow) {
                    errorMessage(err.message, "提示", "请该软件文件夹根目录下db.sqlite3文件属性只读，请取消只读")
                    notionShow = false
                }
                reject(err);
            } else {
                resolve();
            }
        });
    });
}

let customBackup = (key, val) => {
    countBackup(key).then((count) => {
        if (count === 0) {
            addBackup(key, val)
        }
        // else {
        //     setBackup(key, val)
        // }
    })
}

let getLink = (link = '') => {
    return new Promise((resolve, reject) => {
        db.get(`${link}`, (err, row) => {
            if (err) {
                reject(err);
            } else {
                resolve(row);
            }
        });
    });
}

let getAllLink = (link = '') => {
    return new Promise((resolve, reject) => {
        db.all(`${link}`, (err, row) => {
            if (err) {
                reject(err);
            } else {
                resolve(row || []);
            }
        });
    });
}

let deleteCommon = (link = '') => {
    return new Promise((resolve, reject) => {
        db.run(link, function (err) {
            if (err) {
                if (notionShow) {
                    errorMessage(err.message, "提示", "请该软件文件夹根目录下db.sqlite3文件属性只读，请取消只读")
                    notionShow = false
                }
                reject(err);
            } else {
                resolve();
            }
        });
    });
}

let checkColumnExists = (tableName = '', columnName = "", callback) => {
    const query = `PRAGMA table_info(${tableName});`;
    db.all(query, [], (err, rows) => {
        if (err) {
            callback(false);
            return;
        }

        // 检查列名是否存在
        const columnExists = rows.some(row => row.name === columnName);

        // 关闭数据库连接
        callback(columnExists)
    });
}

let showNotification = (title = "", body = '') => {
    new Notification({ title: title, body: body }).show()
    setTimeout(() => {
        notionShow = true
    }, 1000 * 5)
}

let errorMessage = (mgs = '', title = "", body = "") => {
    if (mgs.includes("attempt to write a readonly database")) {
        showNotification(title, body)
    }
}

const existsSync = (locality = '') => {
    return new Promise((resolve, reject) => {
        const filePath = path.join(locality)
        if (fs.existsSync(filePath)) {
            resolve(true)
        } else {
            resolve(false)
        }
    })
}

fs.readFile('./config.ini', 'utf-8', (err, data) => {
    if (err) {
        console.error('无法读取配置文件:', err);
        return;
    }
    // 解析 ini 格式的配置文件
    const config = ini.parse(data);
    let save = config.data.save
    let asave = 'D:/save/'
    if(save) {
        asave = save.replace(/\\/g, "/")
    }
    // 获取 port 参数
    const port = config.server.port
    appPort = port
    appSave = asave
});

const getAppPort = () => {
    return appPort
}

const getAppSave = () => {
    return appSave
}
const store = new Store();
const createWindow = () => {
    // Create the browser window.
    const { width, height } = screen.getPrimaryDisplay().bounds;
    mainWindow = new BrowserWindow({
        width: 400,
        height: 800,
        webPreferences: {
            preload: path.join(__dirname, 'preload.js'),
            nodeIntegration: true,
        },
        icon: path.join(__dirname, './logo.ico')
    });
    protocol.registerFileProtocol('myprotocol', (request, callback) => {
        const url = request.url.replace('myprotocol://', '');
        callback({ path: url });
    });
    db.run(`CREATE TABLE IF NOT EXISTS b_backup (id INTEGER PRIMARY KEY, key TEXT, value TEXT)`, function (err) {
        if (err) {
            return console.log(err.message);
        }
        const allData = store.store;
        if (allData && Object.keys(allData).length > 0) {
            Object.keys(allData).forEach((key) => {
                customBackup(key, allData[key])
            })
            // setTimeout(() => {
            //     store.clear()
            // }, 1000 * 10)
        }
    });
    db.run(`CREATE TABLE IF NOT EXISTS mainUser (
        pkId INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT,
        mid TEXT,
        avatar TEXT
    )`, function (err) {
        if (err) {
            return console.log(err.message);
        }
    });
    db.run(`CREATE TABLE IF NOT EXISTS biLiUser (
        pkId INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT,
        talkerId TEXT,
        avatar TEXT,
        mid TEXT
    )`, function (err) {
        if (err) {
            return console.log(err.message);
        }
    });
    db.run(`CREATE TABLE IF NOT EXISTS biLiMessage (
        pkId INTEGER PRIMARY KEY AUTOINCREMENT,
        mid TEXT,
        senderUid TEXT,
        receiverId TEXT,
        content TEXT,
        msgSeqno TEXT,
        timestamp TEXT,
        msgType TEXT,
        msgKey TEXT,
        msgStatus TEXT,
        msgSource TEXT
    )`, function (err) {
        if (err) {
            return console.log(err.message);
        }
    });

    db.run(`CREATE TABLE IF NOT EXISTS biliImage (
        pkId INTEGER PRIMARY KEY AUTOINCREMENT,
        mid TEXT,
        senderUid TEXT,
        url TEXT,
        localUrl TEXT,
        msgKey TEXT
    )`, function (err) {
        if (err) {
            return console.log(err.message);
        }
    });
    ipcMain.on('app-post', async (event) => {
        event.returnValue = getAppPort()
    })
    ipcMain.on('app-save', async (event) => {
        event.returnValue = getAppSave()
    })


    //   screenshots = new Screenshots()

    ipcMain.on('window_size', async (event) => {
        event.returnValue = mainWindow.getSize();
    })

    ipcMain.on('electron-store-get', async (event, val) => {
        getBackup(val).then((res) => {
            event.returnValue = res;
        })
        // event.returnValue = store.get(val);
    });
    ipcMain.on('electron-store-set', async (event, key, val) => {
        countBackup(key).then((count) => {
            if (count === 0) {
                addBackup(key, val)
            } else {
                setBackup(key, val)
            }
        })
        // store.set(key, val);
    });
    ipcMain.on('electron-store-clear', async (event) => {
        deleteBackup()
        // store.clear();
    });
    ipcMain.on('electron-store-path', async (event) => {
        event.returnValue = store.path;
    });
    ipcMain.on('open-window', async (event, url, specs, windowFlag = true) => {
        const { width, height } = screen.getPrimaryDisplay().bounds;
        const newWindow = new BrowserWindow({
            width: specs && specs.width ? specs.width : width,
            height: specs && specs.height ? specs.height : height,
            center: true,
            webPreferences: {
                preload: path.join(__dirname, 'preload.js'),
            },
            icon: path.join(__dirname, './logo.ico')
        });
        if (windowFlag) {
            newWindow.loadFile(path.join(__dirname, `index.html`), { hash: url });
        } else {
            newWindow.loadURL(url);
        }
        newWindow.setMenuBarVisibility(false);
        // newWindow.webContents.openDevTools();
    });
    ipcMain.handle('electron-get-csv', async () => {
        let { canceled, filePaths } = await dialog.showOpenDialog({
            title: "请选择csv文件",
            filters: [{ name: 'CSV', extensions: ['csv'] }]
        })
        let csvFile;
        if (!canceled && filePaths[0]) {
            let path = filePaths[0];
            csvFile = fs.readFileSync(path, 'utf-8');
            csvFile = Papa.parse(csvFile, { header: true });
        }

        return { canceled, filePaths, csvFile };
    });
    ipcMain.on('save-file', async (event, { data, fileName, filters }) => {
        if (typeof data != 'string') {
            data = JSON.stringify(data);
        }
        let prePath = savePreFilePath || app.getAppPath();
        let { canceled, filePath } = await dialog.showSaveDialog({
            title: '导出',
            defaultPath: path.join(prePath, `${fileName}.json`),
            buttonLabel: "确认",
            filters,
        });
        if (!canceled && filePath) {
            let { dir } = path.parse(filePath);
            savePreFilePath = dir;
            fs.writeFileSync(filePath, data);
        }
    })
    ipcMain.handle('read-file', async (event, filters, multiSelections) => {
        // multiSelections = true;
        let properties = [];
        if (multiSelections) properties.push('multiSelections');
        let { canceled, filePaths } = await dialog.showOpenDialog({
            title: "请选择文件",
            filters: filters,
            properties,
        })
        let fileContents = [];
        if (!canceled && filePaths && filePaths.length > 0) {
            filePaths.forEach(filePath => {
                let content = fs.readFileSync(filePath, 'utf-8');
                content = JSON.parse(content);
                fileContents.push({ filePath, content });
            })
        }
        return ({ canceled, fileContents })
    })

    ipcMain.on('electron-link-get', async (event, val) => {
        getLink(val).then((res) => {
            event.returnValue = res;
        })
    });
    ipcMain.on('electron-allLink-get', async (event, val) => {
        getAllLink(val).then((res) => {
            event.returnValue = res;
        })
    });

    ipcMain.on('capture-screenshot', (event) => {
        // screenshots.startCapture()
        shell.openPath('SnippingTool.exe')
    })
    ipcMain.on('open-path', (event, url) => {
        // screenshots.startCapture()
        const a = url
        shell.openPath(a)
    })
    ipcMain.on('error-path', (event, locality, localUrl, url) => {
        existsSync(url).then(res => {
            if (res) {
                event.returnValue = 'warning'
            } else {
                const imageBuffer = Buffer.from(locality, 'binary');
                fs.writeFile(localUrl, imageBuffer, 'binary', function (err) {
                    if (err) {
                        event.returnValue = 'error'
                    } else {
                        event.returnValue = 'success'
                    }
                });
            }
        })
    })
    ipcMain.on('exists-sync', (event, url) => {
        existsSync(url).then(res => {
            event.returnValue = res
        })
    })

    ipcMain.on('electron-common-clear', async (event, val) => {
        deleteCommon(val).then((res) => {
            event.returnValue = true
        })
    });


    mainWindow.on('closed', () => {
        // 通常，你会在这里关闭所有子窗口  
        app.quit();
    });
    // and load the index.html of the app.
    mainWindow.loadFile(path.join(__dirname, 'index.html'));
    // mainWindow.loadURL('http://localhost:5173/');

    mainWindow.setMenuBarVisibility(false);
};

app.on('ready', createWindow);

app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        app.quit();
    }
    db.close((err) => {
        if (err) {
            return console.error(err.message);
        }
    });
});

app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
        createWindow();
    }
});


app.on('ready', () => {
    let tray = new Tray(path.join(__dirname, './logo.ico'))
    const contextMenu = Menu.buildFromTemplate([{
        label: '显示窗口',
        click: () => {
            // 如果窗口尚未创建，则创建它  
            if (mainWindow === null) {
                createWindow();
            } else {
                // 如果窗口已经被创建但隐藏了，则显示它  
                if (mainWindow.isMinimized()) mainWindow.restore();
                mainWindow.focus();
            }
        }
    },
    // {
    //     label: '系统设置',
    //     click: () => {
    //         const newWindow = new BrowserWindow({
    //             width: 800,
    //             height: 600,
    //             center: true,
    //             webPreferences: {
    //                 preload: path.join(__dirname, 'preload.js'),
    //             },
    //         });
    //         newWindow.loadFile(path.join(__dirname, `index.html`), { hash: "/setting" });
    //         newWindow.setMenuBarVisibility(false);
    //     }
    // },
    {
        label: '刷新',
        click: () => {
            mainWindow.reload(); // 刷新页面
        }
    },
    {
        label: '退出',
        click: () => {
            app.quit();
        }
    }])
    tray.setToolTip('earnings-app') // kline-app / earnings-app
    tray.setContextMenu(contextMenu)
    tray.on('click', () => {
        if (mainWindow === null) {
            createWindow();
        } else {
            // 如果窗口已经被创建但隐藏了，则显示它  
            if (mainWindow.isMinimized()) mainWindow.restore();
            mainWindow.focus();
        }
    });
})
